import * as THREE from "three";
import { InstancedMesh, Mesh, Object3D } from 'three';
import { Vector3, Material, BufferGeometry } from 'three';

const base = new Object3D();
const baseScale = new Vector3( 1, 1, 1 );
export function createInstancedMesh ( object: Object3D, positions: Vector3[] = [], rotations: Vector3[] = [], scales: Vector3[] | number = 1 ) {
    if ( object instanceof Mesh ) {
        const { geometry, material } = object;

        const mesh = new InstancedMesh( geometry, material, positions.length );

        if ( positions.length === 0 ) {
            console.error( `${ object.name }:创建实例化对象，无位置信息` );
            return base;
        }

        if ( !Array.isArray( positions ) ) {
            console.error( `${ object.name }:创建实例化对象，位置信息必须是 THREE.Vector3[]` );
            return base;
        }

        const p0 = positions[ 0 ];
        if ( !( p0 instanceof Vector3 ) ) {
            console.error( `${ object.name }:创建实例化对象，位置信息必须是 THREE.Vector3[]` );
            return base;
        }

        positions.forEach( ( position, index ) => {

            const matrix = new THREE.Matrix4();

            if ( !Array.isArray( scales ) ) {
                matrix.makeScale( scales, scales, scales );
            } else {
                const { x, y, z } = scales[ index ] || baseScale;
                matrix.makeScale( x, y, z );
            }

            matrix.setPosition( position );

            if ( rotations.length ) {
                // matrix.multiply( new THREE.Matrix4().makeRotationX( rotations[ index ].x ) );
                // matrix.multiply( new THREE.Matrix4().makeRotationY( rotations[ index ].y ) );
                // matrix.multiply( new THREE.Matrix4().makeRotationZ( rotations[ index ].z ) );
            }

            mesh.setMatrixAt( index, matrix );
        } );


        return mesh;
    } else if ( object instanceof THREE.Group ) {
        const group = new THREE.Group();
        object.traverse( child => {
            if ( child instanceof THREE.Mesh ) {
                group.add( createInstancedMesh( child, positions, rotations, scales ) );
            }
        } );
        return group;
    } else {
        const group = new THREE.Group();
        object.children.forEach( item => {
            group.add( createInstancedMesh( item, positions, rotations, scales ) );
        } );
        return group;
    }
}
